import sys
import os
from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
                               QWidget, QToolBar, QStatusBar, QFileDialog,
                               QMessageBox, QPushButton, QLabel, QSlider)
from PySide6.QtGui import QAction, QKeySequence, QIcon, QPixmap
from PySide6.QtCore import Qt, QSize
from PySide6.QtPdf import QPdfDocument
from PySide6.QtPdfWidgets import QPdfView


class PdfViewer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.current_file = None
        self.init_ui()

    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("PDF 查看器 - QPdfView 示例")
        self.setGeometry(100, 100, 1200, 800)

        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)

        # 创建 PDF 文档和视图
        self.pdf_document = QPdfDocument(self)
        self.pdf_view = QPdfView()
        self.pdf_view.setDocument(self.pdf_document)

        # 设置初始缩放模式
        self.pdf_view.setZoomMode(QPdfView.ZoomMode.FitToWidth)

        main_layout.addWidget(self.pdf_view)

        # 创建工具栏
        self.create_toolbar()

        # 创建状态栏
        self.create_statusbar()

        # 连接信号
        self.connect_signals()

    def create_toolbar(self):
        """创建工具栏"""
        toolbar = QToolBar("主工具栏")
        toolbar.setIconSize(QSize(24, 24))
        self.addToolBar(toolbar)

        # 打开文件动作
        self.open_action = QAction("打开", self)
        self.open_action.setShortcut(QKeySequence.Open)
        self.open_action.triggered.connect(self.open_file)
        toolbar.addAction(self.open_action)

        toolbar.addSeparator()

        # 缩放动作
        self.zoom_in_action = QAction("放大", self)
        self.zoom_in_action.setShortcut(QKeySequence.ZoomIn)
        self.zoom_in_action.triggered.connect(self.zoom_in)
        toolbar.addAction(self.zoom_in_action)

        self.zoom_out_action = QAction("缩小", self)
        self.zoom_out_action.setShortcut(QKeySequence.ZoomOut)
        self.zoom_out_action.triggered.connect(self.zoom_out)
        toolbar.addAction(self.zoom_out_action)

        # 缩放模式按钮
        toolbar.addSeparator()
        self.fit_width_btn = QPushButton("适应宽度")
        self.fit_width_btn.clicked.connect(lambda: self.set_zoom_mode(QPdfView.ZoomMode.FitToWidth))
        toolbar.addWidget(self.fit_width_btn)

        self.fit_page_btn = QPushButton("适应页面")
        self.fit_page_btn.clicked.connect(lambda: self.set_zoom_mode(QPdfView.ZoomMode.FitInView))
        toolbar.addWidget(self.fit_page_btn)

        self.actual_size_btn = QPushButton("实际大小")
        self.actual_size_btn.clicked.connect(self.actual_size)
        toolbar.addWidget(self.actual_size_btn)

        # 页面导航
        toolbar.addSeparator()
        self.prev_page_action = QAction("上一页", self)
        self.prev_page_action.setShortcut(Qt.Key_Left)
        self.prev_page_action.triggered.connect(self.previous_page)
        toolbar.addAction(self.prev_page_action)

        self.next_page_action = QAction("下一页", self)
        self.next_page_action.setShortcut(Qt.Key_Right)
        self.next_page_action.triggered.connect(self.next_page)
        toolbar.addAction(self.prev_page_action)
        toolbar.addAction(self.next_page_action)

        # 页面跳转
        toolbar.addSeparator()
        self.page_label = QLabel("页面:")
        toolbar.addWidget(self.page_label)

        self.page_slider = QSlider(Qt.Horizontal)
        self.page_slider.setMinimum(1)
        self.page_slider.setMaximum(1)
        self.page_slider.setFixedWidth(100)
        self.page_slider.valueChanged.connect(self.on_page_slider_changed)
        toolbar.addWidget(self.page_slider)

        self.page_info_label = QLabel("0 / 0")
        self.page_info_label.setFixedWidth(60)
        toolbar.addWidget(self.page_info_label)

    def create_statusbar(self):
        """创建状态栏"""
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)

        # 缩放信息标签
        self.zoom_label = QLabel("缩放: 100%")
        self.status_bar.addPermanentWidget(self.zoom_label)

        # 文档信息标签
        self.doc_info_label = QLabel("就绪")
        self.status_bar.addWidget(self.doc_info_label)

    def connect_signals(self):
        """连接信号"""
        self.pdf_document.statusChanged.connect(self.on_document_status_changed)

        # 监听缩放变化
        self.pdf_view.zoomFactorChanged.connect(self.on_zoom_changed)

        # 监听页面变化
        if self.pdf_view.pageNavigator():
            self.pdf_view.pageNavigator().currentPageChanged.connect(self.on_page_changed)

    def open_file(self):
        """打开 PDF 文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "打开 PDF 文件",
            "",
            "PDF 文件 (*.pdf);;所有文件 (*)"
        )

        if file_path:
            self.load_pdf_file(file_path)

    def load_pdf_file(self, file_path):
        """加载 PDF 文件"""
        if not os.path.exists(file_path):
            QMessageBox.warning(self, "错误", f"文件不存在: {file_path}")
            return

        # 加载 PDF 文档
        self.pdf_document.load(file_path)
        self.current_file = file_path

        # 更新窗口标题
        file_name = os.path.basename(file_path)
        self.setWindowTitle(f"PDF 查看器 - {file_name}")

    def zoom_in(self):
        """放大视图"""
        current_zoom = self.pdf_view.zoomFactor()
        self.pdf_view.setZoomFactor(current_zoom * 1.2)
        self.pdf_view.setZoomMode(QPdfView.ZoomMode.Custom)

    def zoom_out(self):
        """缩小视图"""
        current_zoom = self.pdf_view.zoomFactor()
        self.pdf_view.setZoomFactor(current_zoom / 1.2)
        self.pdf_view.setZoomMode(QPdfView.ZoomMode.Custom)

    def actual_size(self):
        """实际大小"""
        self.pdf_view.setZoomFactor(1.0)
        self.pdf_view.setZoomMode(QPdfView.ZoomMode.Custom)

    def set_zoom_mode(self, mode):
        """设置缩放模式"""
        self.pdf_view.setZoomMode(mode)

    def previous_page(self):
        """上一页"""
        navigator = self.pdf_view.pageNavigator()
        if navigator:
            current_page = navigator.currentPage()
            if current_page > 0:
                navigator.jump(current_page - 1, QPdfView.ZoomMode.Custom)

    def next_page(self):
        """下一页"""
        navigator = self.pdf_view.pageNavigator()
        if navigator:
            current_page = navigator.currentPage()
            if current_page < self.pdf_document.pageCount() - 1:
                navigator.jump(current_page + 1, QPdfView.ZoomMode.Custom)

    def on_page_slider_changed(self, value):
        """页面滑块变化"""
        navigator = self.pdf_view.pageNavigator()
        if navigator and 0 <= value - 1 < self.pdf_document.pageCount():
            navigator.jump(value - 1, QPdfView.ZoomMode.Custom)

    def on_document_status_changed(self, status):
        """处理文档状态变化"""
        if status == QPdfDocument.Status.Ready:
            page_count = self.pdf_document.pageCount()
            self.doc_info_label.setText(f"文档已加载，共 {page_count} 页")

            # 更新页面滑块
            self.page_slider.setMaximum(max(1, page_count))
            self.page_slider.setValue(1)

            # 更新页面信息
            self.update_page_info(0)

            # 获取文档元数据
            self.show_document_metadata()

        elif status == QPdfDocument.Status.Loading:
            self.doc_info_label.setText("正在加载文档...")
        elif status == QPdfDocument.Status.Error:
            self.doc_info_label.setText("加载文档时出错")
            QMessageBox.critical(self, "错误", f"无法加载 PDF 文件: {self.pdf_document.error()}")

    def on_zoom_changed(self, factor):
        """缩放变化处理"""
        zoom_percent = int(factor * 100)
        self.zoom_label.setText(f"缩放: {zoom_percent}%")

    def on_page_changed(self, page):
        """页面变化处理"""
        self.update_page_info(page)
        self.page_slider.setValue(page + 1)

    def update_page_info(self, current_page):
        """更新页面信息"""
        total_pages = self.pdf_document.pageCount()
        self.page_info_label.setText(f"{current_page + 1} / {total_pages}")

    def show_document_metadata(self):
        """显示文档元数据"""
        metadata = {
            '标题': self.pdf_document.metaData(QPdfDocument.MetaDataField.Title),
            '作者': self.pdf_document.metaData(QPdfDocument.MetaDataField.Author),
            '主题': self.pdf_document.metaData(QPdfDocument.MetaDataField.Subject),
            '创建者': self.pdf_document.metaData(QPdfDocument.MetaDataField.Creator),
        }

        # 过滤空值
        metadata = {k: v for k, v in metadata.items() if v}

        if metadata:
            info_text = " | ".join([f"{k}: {v}" for k, v in metadata.items()])
            self.status_bar.showMessage(info_text, 5000)  # 显示5秒


def main():
    # 创建应用实例
    app = QApplication(sys.argv)

    # 设置应用属性
    app.setApplicationName("PDF Viewer")
    app.setApplicationVersion("1.0")

    # 创建并显示主窗口
    viewer = PdfViewer()
    viewer.show()

    # 运行应用
    sys.exit(app.exec())


if __name__ == "__main__":
    main()